﻿#ifndef XQACCOUNTRESPONSE_H
#define XQACCOUNTRESPONSE_H
#include"XQHead.h"
#include"XQHttpReplyObject.h"
#include"XQHttpAccount.h"
#include"XQAccountData.h"
#include<QJsonDocument>
#include<QHash>
#include<QReadWriteLock>
#include<QSharedPointer>
#include<XQMySql.hpp>
//http账号管理服务端回复方法
class XQHttpReplyAccount:public XQHttpReplyObject
{
	Q_OBJECT
public:
	XQHttpReplyAccount(QObject* parent = nullptr);
public:
	//邮箱绑定账号数量
	int emailBindAccountCount()const;
	//头像最大大小
	QSize portraitMaxSize()const;
	//是否登录了
	bool isLogin(QIODevice* socket);
	//登录用户账号
	QString loginAccount(QIODevice* socket);
	//登录用户账号列表
	QStringList loginAccounts();
	//从json中解密
	virtual QString account_decode(const QJsonObject& json);
	//从json中解密
	virtual QString password_decode(const QJsonObject& json);
	//从json中解密
	virtual QString newPassword_decode(const QJsonObject& json);
public:
	void setUserMysql(XQMySql* mysql);
	void setMail(XQMail*mail);
	//设置内存清理时间间隔
	void setRamClearInterval(int msec);
	//设置邮箱绑定账号数量
	void setEmailBindAccountCount(int count);
	//设置头像最大大小
	void setPortraitMaxSize(const QSize& size);
	void setPortraitMaxSize(int w,int h);
	//设置账号正则表达式
	void setAccountFormat(const QString& regex);
	//设置密码正则表达式
	void setPasswordFormat(const QString& regex);
public:
	//账号是否存在
	bool isAccountExist_mysql(const QString& account, QSharedPointer<XQMySql> mysql=nullptr);
	//邮箱绑定账号数量
	int emailBindAccountCount_mysql(const QString& account, QSharedPointer<XQMySql> mysql = nullptr);
	//在数据库中查询指定字段账号信息
	QVariant accountInfo_mysql(const QString& account, const QString& field, QSharedPointer<XQMySql> mysql = nullptr);
	//在数据库中查询指定字段账号信息
	XQAccountData accountInfo_mysql(const QString& account,const QStringList& fields, QSharedPointer<XQMySql> mysql = nullptr);
signals:

protected slots:
	//定时器任务 主要做清理
	void timedTask();
	//清理验证码
	void clearVerify(QHash<QString, HttpAccount::Verify*>& hash);
	//清理指定的验证码
	void clearVerify(QHash<QString, HttpAccount::Verify*>& hash,const QString& key);
	//mysql检查初始化
	void userMysql_init();
protected:
	//是否接受
	bool isAccepted(XQHttpHeadObject* head) const override;
	//回复
	XQHttpHeadReply reply(QIODevice* socket, XQHttpHeadRequest* header)override;
	//缓存处理
	void buffer(QIODevice* socket, XQHttpHeadObject* head, const QByteArray& buffer)override;
	//有客户端断开连接
	void clientdisconnected(QIODevice* socket)override;
protected:
	//获得邮箱验证码类
	HttpAccount::Verify* emailVerifyClass(const QString& email);
	//获得账号验证码类
	HttpAccount::Verify* accountVerifyClass(const QString& email);
	//获得相交的字段
	QStringList intersectFields(const QStringList& fields,const QSet<QString>& except= QSet<QString>()/*排除的字段*/);
	//判断字符串是否是邮箱
	bool isEmailFormat(const QString& email);
	//判断是否是指定账号格式
	bool isAccountFormat(const QString& account);
	//判断是否是指定密码格式
	bool isPasswordFormat(const QString& password);
	//邮箱格式识别
	bool emailFormatRecognition(const QString& email, HttpAccount::Result result, XQHttpHeadReply& reply);
	//账号格式识别
	bool accountFormatRecognition(const QString& account, HttpAccount::Result result, XQHttpHeadReply& reply);
	//密码格式识别
	bool passwordFormatRecognition(const QString& password, HttpAccount::Result result, XQHttpHeadReply& reply);
	//邮箱账号识别  判断输入的邮箱和账号是否是一起匹配的
	bool emailAccountRecognition(const QString& email, const QString& account, HttpAccount::Result result, XQHttpHeadReply& reply, QSharedPointer<XQMySql> mysql);
	//验证码识别
	bool verifyRecognition(QHash<QString, HttpAccount::Verify*>& hash, const QString& key, const QString& verify,const QString& email , HttpAccount::Result result, XQHttpHeadReply& reply);
	//身份认证
	bool authentication(const QString& account, const QString& password, HttpAccount::Result result, XQHttpHeadReply& reply, QSharedPointer<XQMySql> mysql);
	//发送邮件验证码
	bool sendMailVerify(const QString& email, HttpAccount::Verify* verify, HttpAccount::Result result, XQHttpHeadReply& reply);
protected://业务处理
	XQHttpHeadReply Account_NewEmailVerify(QIODevice* socket, const QJsonObject& json);//新邮箱验证码
	XQHttpHeadReply Account_BindEmailVerify(QIODevice* socket, const QJsonObject& json);//与账号绑定的邮箱验证码
	XQHttpHeadReply Account_Login(QIODevice* socket, const QJsonObject& json);//登录
	XQHttpHeadReply Account_Logout(QIODevice* socket, const QJsonObject& json);//退出登录
	XQHttpHeadReply Account_Register(QIODevice* socket, const QJsonObject& json);//注册
	XQHttpHeadReply Account_ModifyPassword(QIODevice* socket, const QJsonObject& json);//修改密码
	XQHttpHeadReply Account_ModifyInfo(QIODevice* socket, const QJsonObject& json);//修改信息
	XQHttpHeadReply Account_ModifyEmail(QIODevice* socket, const QJsonObject& json);//修改邮箱
	XQHttpHeadReply Account_portrait(QIODevice* socket, const QJsonObject& json);//返回头像信息
	XQHttpHeadReply Account_Info(QIODevice* socket, const QJsonObject& json);//返回获取信息
protected:
	XQMySql* m_userMysql = nullptr;
	XQMail* m_mail = nullptr;
	QTimer* m_timer = nullptr;
	int m_emailBindAccountCount = 1;//邮箱绑定账号数量
	QString m_accountFormat;// 账号格式 正则表达式
	QString m_passwordFormat;//密码格式 正则表达式
	QSize m_portraitMaxSize=QSize(400,400);//头像最大大小
	//保存登录状态
	QReadWriteLock m_loginAccountLock;
	QHash<QIODevice*,QString> m_loginAccount;//登陆的用户(套接字,账号)
	//验证码请求
	QReadWriteLock m_verifyLock;
	QHash<QString, HttpAccount::Verify*> m_accountVerify;//账号验证码(账号,信息)
	QHash<QString, HttpAccount::Verify*> m_emailVerify;//邮箱验证码(邮箱,信息)
};
#endif // !XQAccountResponse_H
